/**
 * Background Script 主入口
 * 模块化的 Background Script，采用服务导向架构
 */

import { setupMessageHandlers } from "./MessageHandlers";
import { initializeEventHandlers } from "./EventHandlers";
import { StorageService } from "./services/StorageService";
import { TabService } from "./services/TabService";
import { ConfigManager } from "./services/ConfigService";
import { MessageRouter } from "@utils/messaging";
import { BaseMessage, MessageType } from "@utils/types";
import { DEBUG } from "@utils/constants";

export default defineBackground(() => {
  console.log("🚀 Background Script Starting...", {
    id: browser.runtime.id,
    timestamp: new Date().toISOString(),
    version: browser.runtime.getManifest().version,
  });

  // 初始化服务实例
  const services = initializeServices();

  // 设置消息处理器
  setupMessageHandlers(services.messageRouter, services.storageService, services.tabService, services.configManager);

  // 初始化事件处理器
  initializeEventHandlers(services.storageService, services.tabService, services.configManager);

  // 启动消息监听
  services.messageRouter.startListening();

  // 启动定期任务
  startPeriodicTasks(services);

  console.log("✅ Background Script initialized successfully");
});

/**
 * 初始化所有服务实例
 */
function initializeServices() {
  console.log("🔧 Initializing services...");

  // 创建服务实例
  const storageService = StorageService.getInstance();
  const tabService = TabService.getInstance();
  const configManager = ConfigManager.getInstance();
  const messageRouter = new MessageRouter();

  // 配置消息路由器中间件
  messageRouter.use(validateMessageMiddleware);
  messageRouter.use(loggingMiddleware);

  // 添加限流中间件（防止消息洪水）
  messageRouter.use(createRateLimitMiddleware());

  console.log("✅ Services initialized");

  return {
    storageService,
    tabService,
    configManager,
    messageRouter,
  };
}

/**
 * 消息验证中间件
 */
function validateMessageMiddleware(message: BaseMessage): boolean {
  // 验证消息基本格式
  if (!message.type) {
    console.warn("Message missing type field");
    return false;
  }

  // 验证消息类型是否有效
  if (!Object.values(MessageType).includes(message.type)) {
    console.warn("Invalid message type:", message.type);
    return false;
  }

  return true;
}

/**
 * 日志记录中间件
 */
function loggingMiddleware(message: BaseMessage, sender: Browser.runtime.MessageSender): boolean {
  if (DEBUG) {
    console.log("📨 Message received:", {
      type: message.type,
      sender: sender.tab ? `tab:${sender.tab.id}` : sender.url,
      timestamp: new Date().toISOString(),
    });
  }
  return true;
}

/**
 * 创建限流中间件
 */
function createRateLimitMiddleware() {
  /** 记录每个发送者的请求时间戳 */
  const rateLimits = new Map<string, number[]>();
  /** 限流时间窗口(毫秒) - 1分钟 */
  const RATE_LIMIT_WINDOW = 60 * 1000;
  /** 时间窗口内最大请求数 */
  const MAX_REQUESTS_PER_WINDOW = 100;

  // 开发环境直接放行，避免影响调试
  if (DEBUG) {
    return () => true;
  }

  const EXEMPT_TYPES = new Set<BaseMessage["type"]>([
    MessageType.SAVE_DATA,
    MessageType.GET_DATA,
    MessageType.STORAGE_CHANGED as any,
    MessageType.GET_TAB_INFO,
    MessageType.COUNT_ELEMENTS,
    MessageType.INJECT_CSS,
  ]);

  return (message: BaseMessage, sender: Browser.runtime.MessageSender): boolean => {
    // 放行白名单消息类型，避免阻塞核心状态同步
    if (EXEMPT_TYPES.has(message.type)) return true;
    const senderId = sender.tab?.id?.toString() || sender.url || "unknown";
    const now = Date.now();

    if (!rateLimits.has(senderId)) {
      rateLimits.set(senderId, []);
    }

    const requests = rateLimits.get(senderId)!;

    // 清理过期的请求
    const validRequests = requests.filter((time) => now - time < RATE_LIMIT_WINDOW);
    rateLimits.set(senderId, validRequests);

    // 检查是否超过限制
    if (validRequests.length >= MAX_REQUESTS_PER_WINDOW) {
      console.warn(`Rate limit exceeded for sender: ${senderId}`);
      return false;
    }

    // 记录当前请求
    validRequests.push(now);
    rateLimits.set(senderId, validRequests);

    return true;
  };
}

/**
 * 启动定期任务
 */
function startPeriodicTasks(services: {
  storageService: StorageService;
  tabService: TabService;
  configManager: ConfigManager;
}) {
  console.log("🔄 Starting periodic tasks...");

  // 清理过期缓存（每10分钟）
  setInterval(
    () => {
      services.storageService.clearExpiredCache();
      if (DEBUG) {
        console.log("🧹 Expired cache cleared");
      }
    },
    10 * 60 * 1000
  );

  // 系统状态检查（每5分钟）
  setInterval(
    async () => {
      try {
        await performHealthCheck(services);
      } catch (error) {
        console.error("Health check failed:", error);
      }
    },
    5 * 60 * 1000
  );

  // 数据备份（每小时）
  setInterval(
    async () => {
      try {
        await performDataBackup(services.storageService);
      } catch (error) {
        console.error("Data backup failed:", error);
      }
    },
    60 * 60 * 1000
  );
}

/**
 * 执行系统健康检查
 */
async function performHealthCheck(services: { storageService: StorageService; tabService: TabService }) {
  if (!DEBUG) return;

  const [tabStats, storageStats] = await Promise.all([
    services.tabService.getTabStats(),
    services.storageService.getStorageStats(),
  ]);

  const healthReport = {
    timestamp: new Date().toISOString(),
    uptime: Date.now() - performance.now(),
    tabs: {
      total: tabStats.total,
      active: tabStats.active,
      scriptable: tabStats.scriptable,
    },
    storage: {
      items: storageStats.totalItems,
      sizeKB: Math.round(storageStats.bytesInUse / 1024),
    },
    memory: {
      used: (performance as any).memory?.usedJSHeapSize || "N/A",
      total: (performance as any).memory?.totalJSHeapSize || "N/A",
    },
  };

  console.log("💓 System Health Check:", healthReport);

  // 检查是否有异常情况
  if (storageStats.bytesInUse > 5 * 1024 * 1024) {
    // 5MB
    console.warn("⚠️ Storage size is getting large:", `${Math.round(storageStats.bytesInUse / 1024 / 1024)}MB`);
  }

  if (tabStats.total > 50) {
    console.warn("⚠️ Large number of tabs detected:", tabStats.total);
  }
}

/**
 * 执行数据备份
 */
async function performDataBackup(storageService: StorageService) {
  try {
    const allData = await storageService.getAll();
    const backup = {
      timestamp: Date.now(),
      version: browser.runtime.getManifest().version,
      data: allData,
    };

    // 保存备份到特殊的备份键
    await storageService.save(`backup_${Date.now()}`, backup);

    // 保留最近的3个备份
    await cleanupOldBackups(storageService);

    if (DEBUG) {
      console.log("💾 Data backup completed");
    }
  } catch (error) {
    console.error("Data backup failed:", error);
  }
}

/**
 * 清理旧备份
 */
async function cleanupOldBackups(storageService: StorageService) {
  try {
    const stats = await storageService.getStorageStats();
    const backupKeys = stats.keys.filter((key) => key.startsWith("backup_")).sort();

    // 保留最近的3个备份
    if (backupKeys.length > 3) {
      const keysToDelete = backupKeys.slice(0, backupKeys.length - 3);
      for (const key of keysToDelete) {
        await storageService.delete(key);
      }

      if (DEBUG) {
        console.log(`🧹 Cleaned up ${keysToDelete.length} old backups`);
      }
    }
  } catch (error) {
    console.error("Backup cleanup failed:", error);
  }
}
